package com.fishingwithme.android.ui.viewmodels

import android.util.Log
import androidx.lifecycle.viewModelScope
import com.fishingwithme.android.data.local.PreferencesManager
import com.fishingwithme.android.data.location.LocationService
import com.fishingwithme.android.data.model.CircleMessage
import com.fishingwithme.android.data.model.City
import com.fishingwithme.android.data.model.CityLocation
import com.fishingwithme.android.data.model.Position
import com.fishingwithme.android.data.repository.FishingRepository
import com.fishingwithme.android.utils.PermissionHelper
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.firstOrNull
import kotlinx.coroutines.launch
import javax.inject.Inject

data class AnybitingUiState(
    val isLoading: Boolean = false,
    val messages: List<CircleMessage<*>> = emptyList(),
    val error: String? = null,
    val isRefreshing: Boolean = false,
    val hasMoreData: Boolean = true,

    val currentCityLocation: CityLocation = CityLocation(null, null),
    val hasLocationPermission: Boolean = false,
    val isLoadingLocation: Boolean = false,
    val searchResults: List<City> = emptyList(),
    val isSearching: Boolean = false
)

@HiltViewModel
class AnybitingViewModel @Inject constructor(
    private val repository: FishingRepository,
    private val locationService: LocationService,
    private val permissionHelper: PermissionHelper,
    private val preferencesManager: PreferencesManager
) : BaseViewModel(preferencesManager) {

    private val _uiState = MutableStateFlow(AnybitingUiState())
    val uiState: StateFlow<AnybitingUiState> = _uiState.asStateFlow()

    private var currentCursor = ""


    fun checkLocationPermission() {
        val hasPermission = permissionHelper.hasLocationPermission()
        Log.d("AnybitingViewModel", "Location permission: $hasPermission")
        _uiState.value = _uiState.value.copy(hasLocationPermission = hasPermission)
    }

    fun getCurrentLocation() {
        checkLocationPermission()
        if (!_uiState.value.hasLocationPermission) {
            return
        }

        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isLoadingLocation = true)

            try {
                locationService.getCurrentLocation().fold(
                    onSuccess = { position ->
                        Log.d(
                            "AnybitingViewModel",
                            "Got location: ${position.latitude}, ${position.longitude}"
                        )

                        val cl = CityLocation(null, position)
                        _uiState.value = _uiState.value.copy(
                            currentCityLocation = cl,
                            isLoadingLocation = false
                        )

                        preferencesManager.saveLocation(position.latitude, position.longitude)

                        // Get city name and update city code for better content
                        getCityByPosition(position)
                    },
                    onFailure = { exception ->
                        Log.e("AnybitingViewModel", "Failed to get location: ${exception.message}")
                        _uiState.value = _uiState.value.copy(
                            isLoadingLocation = false,
                            error = "获取位置失败: ${exception.message}"
                        )
                    }
                )
            } catch (e: Exception) {
                Log.e("AnybitingViewModel", "Location service error: ${e.message}")
                _uiState.value = _uiState.value.copy(
                    isLoadingLocation = false,
                    error = "位置服务错误: ${e.message}"
                )
            }
        }
    }

    private fun getCityByPosition(position: Position) {
        viewModelScope.launch {
            try {
                _uiState.value = _uiState.value.copy(
                    error = null,
                    isLoadingLocation = true
                )
                val result = repository.getCityByPosition(position).first()
                result.fold(
                    onSuccess = { city ->
                        val cl = CityLocation(city, position)
                        _uiState.value = _uiState.value.copy(
                            currentCityLocation = cl
                        )

                        viewModelScope.launch {
                            preferencesManager.saveCityLocation(cl)
                        }

                    },
                    onFailure = {
                        _uiState.value = _uiState.value.copy(
                            error = "无法获取城市信息，请检查网络连接后重试",
                            isLoadingLocation = false
                        )
                    }
                )
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    error = "城市信息获取失败，请检查网络连接后重试",
                    isLoadingLocation = false
                )
            }
        }
    }

    fun loadCircleMessagesByCity(cityCode: String) {
        Log.d("AnybitingViewModel", "Starting to load messages for city: $cityCode")
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isLoading = true, error = null)

            try {
                val result = repository.loadCircleMessagesByCity(cityCode).first()
                result.fold(
                    onSuccess = { messages ->
                        Log.d("AnybitingViewModel", "Successfully loaded ${messages.size} messages")
                        currentCursor = messages.lastOrNull()?.cursor ?: ""
                        _uiState.value = _uiState.value.copy(
                            isLoading = false,
                            messages = messages,
                            hasMoreData = messages.isNotEmpty()
                        )

                        // Save the city code to preferences
                        // We need to update the current city location in the UI state
                        val currentCityLocation = _uiState.value.currentCityLocation
                        val updatedCityLocation = currentCityLocation.copy(
                            city = currentCityLocation.city?.copy(cityCode = cityCode) ?: City(
                                cityCode,
                                null
                            )
                        )
                        _uiState.value =
                            _uiState.value.copy(currentCityLocation = updatedCityLocation)

                        // Save to local storage
                        viewModelScope.launch {
                            preferencesManager.saveCityLocation(updatedCityLocation)
                        }
                    },
                    onFailure = { exception ->
                        val handledException = handleException(exception as Exception)
                        Log.e(
                            "AnybitingViewModel",
                            "Failed to load messages: ${handledException.message}"
                        )
                        _uiState.value = _uiState.value.copy(
                            isLoading = false,
                            error = handledException.message ?: "加载失败"
                        )
                    }
                )
            } catch (e: Exception) {
                Log.e("AnybitingViewModel", "Exception loading messages: ${e.message}")
                _uiState.value = _uiState.value.copy(
                    isLoading = false,
                    error = e.message ?: "加载失败"
                )
            }
        }
    }

    fun loadSavedLocationData() {
        viewModelScope.launch {
            // Load saved location (one-time read)
            val locationPair = preferencesManager.getCurrentCityLocation().first()
            locationPair?.let {
                _uiState.value = _uiState.value.copy(
                    currentCityLocation = it
                )
            } ?: run {
                getCurrentLocation()
            }
        }
    }

    fun initializeLocationBasedData() {
        loadSavedLocationData()
        viewModelScope.launch {

            if (_uiState.value.currentCityLocation.city?.cityCode?.isNotEmpty() == true) {
                val cityCode: String = _uiState.value.currentCityLocation.city?.cityCode ?: ""
                loadCircleMessagesByCity(cityCode)
            } else {
                Log.d("AnybitingViewModel", "No city location")
                _uiState.value = _uiState.value.copy(
                    error = "获取城市代码失败"
                )
            }
        }
    }

    fun refreshMessages() {
        _uiState.value = _uiState.value.copy(isRefreshing = true, error = null)
        viewModelScope.launch {
            currentCursor = ""

            val city = _uiState.value.currentCityLocation.city ?: run {
                loadSavedLocationData()
                _uiState.value.currentCityLocation.city
            }
            val cityCode: String = city?.cityCode ?: ""
            try {
                val result = repository.loadCircleMessages(cityCode).first()
                result.fold(
                    onSuccess = { messages ->
                        currentCursor = messages.lastOrNull()?.cursor ?: ""
                        _uiState.value = _uiState.value.copy(
                            isRefreshing = false,
                            messages = messages,
                            hasMoreData = messages.isNotEmpty()
                        )
                    },
                    onFailure = { exception ->
                        val handledException = handleException(exception as Exception)
                        _uiState.value = _uiState.value.copy(
                            isRefreshing = false,
                            error = handledException.message ?: "刷新失败"
                        )
                    }
                )
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isRefreshing = false,
                    error = e.message ?: "刷新失败"
                )
            }
        }
    }

    fun loadMoreMessages() {
        if (!_uiState.value.hasMoreData || _uiState.value.isLoading || currentCursor.isEmpty()) {
            return
        }

        // Use current city code or return early if none available
        val cityCode = _uiState.value.currentCityLocation.city?.cityCode ?: return

        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isLoading = true)

            try {
                val result = repository.loadForwardMessages(cityCode, currentCursor).first()
                result.fold(
                    onSuccess = { newMessages ->
                        currentCursor = newMessages.lastOrNull()?.cursor ?: ""
                        val allMessages = _uiState.value.messages + newMessages
                        _uiState.value = _uiState.value.copy(
                            isLoading = false,
                            messages = allMessages,
                            hasMoreData = newMessages.isNotEmpty()
                        )
                    },
                    onFailure = { exception ->
                        val handledException = handleException(exception as Exception)
                        _uiState.value = _uiState.value.copy(
                            isLoading = false,
                            error = handledException.message ?: "加载更多失败"
                        )
                    }
                )
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isLoading = false,
                    error = e.message ?: "加载更多失败"
                )
            }
        }
    }

    fun searchCities(keyword: String) {
        viewModelScope.launch {
            _uiState.value = _uiState.value.copy(isSearching = true, error = null)

            try {
                val result = repository.searchCities(keyword).first()
                result.fold(
                    onSuccess = { cities ->
                        _uiState.value = _uiState.value.copy(
                            isSearching = false,
                            searchResults = cities
                        )
                    },
                    onFailure = { exception ->
                        val handledException = handleException(exception as Exception)
                        _uiState.value = _uiState.value.copy(
                            isSearching = false,
                            error = handledException.message ?: "搜索失败"
                        )
                    }
                )
            } catch (e: Exception) {
                _uiState.value = _uiState.value.copy(
                    isSearching = false,
                    error = e.message ?: "搜索失败"
                )
            }
        }
    }

    fun selectCity(city: City) {
        Log.d("AnybitingViewModel", "Selecting city: ${city.city} (${city.cityCode})")
        // Update UI state with the selected city
        val currentLocation = _uiState.value.currentCityLocation
        val updatedLocation = currentLocation.copy(city = city)
        _uiState.value = _uiState.value.copy(currentCityLocation = updatedLocation)

        // Save to local storage
        viewModelScope.launch {
            preferencesManager.saveCityLocation(updatedLocation)
            // Also save just the city code and name for easier access
            preferencesManager.saveCity(city.cityCode, city.city)
            loadCircleMessagesByCity(city.cityCode)
        }

    }

    fun clearError() {
        _uiState.value = _uiState.value.copy(error = null)
    }


}